﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CrossBasket.cs" company="">
//   
// </copyright>
// <summary>
//   The cross basket.
// </summary>
// --------------------------------------------------------------------------------------------------------------------


using System;
using System.Linq;
using Systemathics.FrameWork;

namespace Systemathics.Automates
{
    [Parameters("Systemathics.Automates.Spread.xlsx")]
    [Pattern("Systemathics.Automates.Spread.dll", "1.0")]
    public sealed class Spread : Strategy
    {
        private bool BuildStarted;
        private Instrument Y, X;
        private SystemathicsSound s;
        private TimeSeries MidSeries;
        private TimeSeries MaxSeries;
        private TimeSeries MinSeries;
        private Guid Y_BuyOrderID, X_SellOrderID, Y_SellOrderID, X_BuyOrderID;
        private OrderExtension ext;

        private int LAG;
        private decimal a;
        private decimal b;
        private decimal ExcessiveSell;
        private decimal ExcessiveBuy;

        private int Gamma = 30000;

        public override void OnStart()
        { 
            
            foreach (Instrument i in Instruments.Values)
            {
                if (Params.ContainsKey(i.StaticData.Name))
                {
                    LAG = (int)((decimal)Params[i.StaticData.Name]["LAG"]);
                    ExcessiveBuy = (decimal)Params[i.StaticData.Name]["ExcessiveBuy"];
                    ExcessiveSell = (decimal)Params[i.StaticData.Name]["ExcessiveSell"];
                    a = (decimal)Params[i.StaticData.Name]["a"];
                    b = (decimal)Params[i.StaticData.Name]["b"];
                    Y = Instruments.Where(z => z.Value.StaticData.Name == (String)Params[i.StaticData.Name]["SecondToTrade"]).FirstOrDefault().Value;
                    X = Instruments.Where(z => z.Value.StaticData.Name == (String)Params[i.StaticData.Name]["FirstToTrade"]).FirstOrDefault().Value;
                }
            }
            Draw(Y, Data.Quote, Axis.Secondary, Axis.Secondary);
            Draw(X, Data.Quote, Axis.Secondary, Axis.Secondary);
            MidSeries = new TimeSeries();
            MaxSeries = new TimeSeries();
            MinSeries = new TimeSeries();
            s = new SystemathicsSound();
            BuildStarted = false;
            ext = new OrderExtension() { Tif = TimeInForce.Day };

            base.OnStart();
        }
        public override void OnBlotter(Blotter blotter)
        {
            if ((blotter.TickInfo == TickInfo.Bid_1 || blotter.TickInfo == TickInfo.Ask_1))
            {
                var t = blotter[QuoteLevel.One].Time;
                MidSeries.Add(t, Y.Blotter[QuoteLevel.One].Mid + a * X.Blotter[QuoteLevel.One].Mid + b);
                MaxSeries.Add(t, MidSeries.Max(LAG));
                MinSeries.Add(t, MidSeries.Min(LAG));
                if (MidSeries.Count() > LAG)
                {
                    if (this[Expo.Working].Bias <= MaxBias)
                    {
                        if (MidSeries.Last() <= MidSeries.Min(LAG))
                        {
                            if ((Y.isShort && X.isLong) || X.isFlat)
                                X_SellOrderID = Sell(X.Id, OrderStyle.Market, X.Blotter[QuoteLevel.One].Mid, (int)(Math.Abs(a) * Gamma), ext);
                            Log(blotter[QuoteLevel.One].Time.ToShortTimeString());
                        }
                        else if (MidSeries.Last() >= MidSeries.Max(LAG))
                        {
                            if ((Y.isLong && X.isShort) || X.isFlat)
                                X_BuyOrderID = Buy(X.Id, OrderStyle.Market, X.Blotter[QuoteLevel.One].Mid, (int)(Math.Abs(a) * Gamma), ext);
                        }
                    }

                    Y.CustomValue1 = MidSeries.Last();
                    Y.CustomValue1 = MidSeries.Max(LAG);
                    X.CustomValue1 = MidSeries.Last();
                    X.CustomValue2 = MidSeries.Min(LAG);
                }
            }
        }
        public override void OnOrder(Order o)
        {
            switch (o.Status)
            {
                case OrderStatus.ACK:
                    //s.ACK();
                    break;
                case OrderStatus.ACK_CANCEL:
                    s.ACK_CANCEL();
                    break;
                case OrderStatus.ACK_MODIFY:
                    s.ACK_MODIFY();
                    break;
                case OrderStatus.FILLED:
                    Hedge(o);
                   // s.FILLED();   
                    break;
                case OrderStatus.PARTIALLY_FILLED:
                    Hedge(o);
                    //s.PARTIALLY_FILLED();
                    break;
                case OrderStatus.REJECT:
                    s.REJECT();
                    break;
                case OrderStatus.REJECT_CANCEL:
                    if (o.CancelRejectionNumber <= 1)
                        Instruments[o.InstrumentId].ReSend(o.Id);
                    // s.REJECT_CANCEL();
                    break;
                case OrderStatus.REJECT_MODIFY:
                    //s.REJECT_MODIFY();

                    // Make something
                    break;
            }
        }
        private void Hedge(Order o)
        {
            if (o.Id == X_BuyOrderID)
                Y_SellOrderID = Sell(Y.Id, OrderStyle.Market, Y.Blotter[QuoteLevel.One].Mid, (int)(o.Executions.Last().Quantity / Math.Abs(a)), ext);
            else if (o.Id == X_SellOrderID)
                Y_BuyOrderID = Buy(Y.Id, OrderStyle.Market, Y.Blotter[QuoteLevel.One].Mid, (int)(o.Executions.Last().Quantity / Math.Abs(a)), ext);
        }
        public override void OnMoneyManagement(MoneyManagement mm)
        {
            switch (mm.Reason)
            {
                case CashManagementTrigger.MaxBiasTriggered:
                    break;
                case CashManagementTrigger.MarginRequirementTriggered:
                    break;
                case CashManagementTrigger.MaxDrawDownTriggered:
                    break;
                case CashManagementTrigger.CashEquityNegative:
                    Log("Strategy Paused -------> CashEquityNegative :" + mm.Amount);
                    //isPaused = true;
                    break;
            }
        }
        public override void OnTradeSeries(TradeSeries series)
        {
        }
        public override void OnQuoteSeries(QuoteSeries series)
        {
        }
        public override void OnBarSeries(BarSeries series)
        {
        }
        public override void OnBuild()
        {
            BuildStarted = true;
            base.OnBuild();
        }
        public override void OnStop()
        {
            //var og = new ToExcel("spread");
            //og.Add(MidSeries);
            //og.Flush();
            //og.Close();

            //var oe = new ToExcel("Max");
            //oe.Add(MaxSeries);
            //oe.Flush();
            //oe.Close();

            //var of = new ToExcel("Min");
            //of.Add(MinSeries);
            //of.Flush();
            //of.Close();

            base.OnStop();
        }
    }
}